package com.ssy.lingxi.platform.manage.serviceimpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.common.constant.CommonConstant;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.component.redis.service.IRedisStringUtils;
import com.ssy.lingxi.platform.manage.api.model.vo.site.SiteSelectVO;
import com.ssy.lingxi.platform.manage.api.model.vo.site.SiteVO;
import com.ssy.lingxi.platform.manage.constant.CommonBooleanEnum;
import com.ssy.lingxi.platform.manage.entity.base.*;
import com.ssy.lingxi.platform.manage.repository.*;
import com.ssy.lingxi.platform.manage.service.ISiteService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 站点 - 业务实现层
 *
 * @author fhj
 * @version 2.0.0
 * @date 2020/9/28
 */
@Service
public class SiteServiceImpl implements ISiteService {

    @Resource
    private SiteRepository siteRepository;
    @Resource
    private SiteShopRepository siteShopRepository;
    @Resource
    private ShopRepository shopRepository;
    @Resource
    private LanguageRepository languageRepository;
    @Resource
    private CurrencyRepository currencyRepository;
    @Resource
    private IRedisStringUtils redisStringUtils;

    /**
     * 查询所有站点
     */
    @Override
    public Wrapper<List<Site>> siteAll() {
        return Wrapper.success(siteRepository.findByState(CommonConstant.State.STATE_START));
    }

    /**
     * 查询站点详情
     */
    @Override
    public Wrapper<SiteVO> details(Long id) {
        SiteVO response = new SiteVO();
        Site site = siteRepository.findById(id).orElse(null);
        if (site != null) {
            BeanUtils.copyProperties(site, response);
            response.setSiteUrl(site.getDomainName());
            Currency currency = currencyRepository.findById(site.getCurrencyId()).orElse(null);
            response.setSymbol(currency == null ? null : currency.getSymbol());

            Language lan = languageRepository.findById(site.getLanguageId()).orElse(null);
            response.setLanguage(lan == null ? "" : lan.getNameEn());
        } else {
            return Wrapper.fail("根据ID找不到站点");
        }

        return Wrapper.success(response);
    }

    /**
     * 根据域名url查询站点详情
     */
    @Override
    public Wrapper<SiteVO> queryByUrlDetails(String url) {
        if (StringUtils.isBlank(url)) {
            return Wrapper.fail("url参数不能为空");
        }
        SiteVO siteResponse = new SiteVO();
        Site site = siteRepository.findAllByUrlEquals(url);
        siteResponse.setId(site.getId());
        siteResponse.setName(site.getName());
        return Wrapper.success(siteResponse);
    }

    /**
     * 获取站点下拉框
     */
    @Override
    public Wrapper<List<SiteSelectVO>> findSiteSelect() {
        List<Site> siteList = siteRepository.findByState(EnableDisableStatus.ENABLE.getCode());
        List<Language> languageList = languageRepository.findAll();

        if (CollectionUtil.isNotEmpty(siteList) && CollectionUtil.isNotEmpty(languageList)) {
            List<SiteSelectVO> list = siteList.stream().map(a -> {
                SiteSelectVO response = new SiteSelectVO();
                response.setId(a.getId());
                response.setSiteName(a.getName());
                response.setDomainName(a.getDomainName());
                response.setLogo(a.getLogo());
                response.setSiteUrl(a.getUrl());
                response.setLanguageId(a.getLanguageId());

                Language language = languageList.stream().filter(b -> b.getId().equals(a.getLanguageId())).findFirst().orElse(null);
                if (language != null) {
                    response.setLanguageName(language.getName());
                    response.setImgUrl(language.getImgUrl());
                }
                return response;
            }).collect(Collectors.toList());
            return Wrapper.success(list);
        }
        return Wrapper.success(new ArrayList<>());
    }

    /**
     * 更新redis中的数据
     */
    private void updateRedisInfo(Long siteId, List<Long> shopIdList) {
        if (shopIdList != null && !shopIdList.isEmpty()) {
            List<Shop> shopList = shopRepository.findByIdIn(shopIdList);
            Map<String, String> map = new HashMap<>();
            shopList.forEach(shop -> map.put(String.valueOf(shop.getId()), JSONUtil.toJsonStr(shop)));
            redisStringUtils.hMSet(Constants.REDIS_KEY_SITE + siteId, map, Constants.REDIS_PLATFORM_MANAGE_INDEX);
        } else {
            //删除redis缓存数据
            redisStringUtils.del(Constants.REDIS_KEY_SITE + siteId, Constants.REDIS_PLATFORM_MANAGE_INDEX);
        }
    }

    /**
     * 初始化到redis
     */
    @Async
    @Override
    public void initToRedis() {
        //先清除缓存
        redisStringUtils.delByPrex(Constants.REDIS_KEY_SITE, Constants.REDIS_PLATFORM_MANAGE_INDEX);
        List<SiteShop> allShopList = new ArrayList<>();
        List<Site> siteList = siteRepository.findByState(CommonConstant.State.STATE_START);
        if (siteList != null && !siteList.isEmpty()) {
            siteList.forEach(site -> {
                List<SiteShop> siteShopList = siteShopRepository.findBySiteId(site.getId());
                allShopList.addAll(siteShopList);
                List<Long> shopIdList = siteShopList.stream().map(SiteShop::getShopId).collect(Collectors.toList());
                updateRedisInfo(site.getId(), shopIdList);
            });
        }
        if (!allShopList.isEmpty()) {
            List<Long> shopIdList = allShopList.stream().map(SiteShop::getShopId).distinct().collect(Collectors.toList());
            updateRedisInfo(0L, shopIdList);
        }
    }

    /**
     * 判断站点是否开启SAAS多租户
     *
     * @param siteId 站点id
     * @return 操作结果为boolean值
     */
    @Override
    public Wrapper<Boolean> enableMultiTenancy(Long siteId) {
        Site site = siteRepository.findById(siteId).orElse(null);
        if (site == null) {
            return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_SY_SITE_INFORMATION_DOES_NOT_EXIST);
        }
        return Wrapper.success(CommonBooleanEnum.YES.getCode().equals(site.getEnableMultiTenancy()));
    }
}
